package com.ruoyi.mongo.config;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.MongoTransactionManager;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.connection.ConnectionPoolSettings;

/**
 * @Description: https://blog.csdn.net/xjmfc/article/details/106929136
 * 	https://blog.csdn.net/qq_32589355/article/details/107624107
 * @ClassName: LogMongoConfiguration
 * @author: wangwk
 * @date: 2020年12月8日 下午7:39:38
 */
 @Configuration
 @ConfigurationProperties(prefix = "spring.data.mongodb.test")
public class SyczcxMongoConfiguration {
	
	@Autowired
    private MongoSettingsProperties mongoSettingsProperties;
	private ArrayList<String> addresses;
	private String database;
	private String authenticationDatabase;
	private String username;
	private String password;

	public ArrayList<String> getAddresses() {
		return addresses;
	}
	public void setAddresses(ArrayList<String> addresses) {
		this.addresses = addresses;
	}
	public String getDatabase() {
		return database;
	}
	public void setDatabase(String database) {
		this.database = database;
	}
	public String getAuthenticationDatabase() {
		return authenticationDatabase;
	}
	public void setAuthenticationDatabase(String authenticationDatabase) {
		this.authenticationDatabase = authenticationDatabase;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @Description: 功能描述
	 * 		日志MongoDB模版
	 * 
	 * @param: 参数描述
	 * @return
	 * @throws: 异常描述
	 *
	 * @version: v1.0.3
	 * @author: wangwk
	 * @date: 2021年9月14日 上午10:17:49
	 *
	 * Modification History:
	 * Date         Author          Version            Description
	 * ---------------------------------------------------------*
	 * 2021年9月14日   wangwk          v1.0.3.1               创建
	 */
	@Bean(name = "mongo_test")
	public MongoTemplate mongoTemplate() {
		/**
		 * 	MongoDB地址列表
		 */
		List<ServerAddress> serverAddresses = new ArrayList<ServerAddress>();
		for (String hostport : this.addresses) {
			String[] hostportArray = hostport.split(":");
			String host = hostportArray[0];
			Integer port = Integer.parseInt(hostportArray[1]);
			ServerAddress serverAddress = new ServerAddress(host, port);
			serverAddresses.add(serverAddress);
		}
		/**
		 * 	MongoDB客户端配置
		 */
		ConnectionPoolSettings connectionPoolSettings = ConnectionPoolSettings.builder()
						.minSize(mongoSettingsProperties.getMinSize())
						.maxSize(mongoSettingsProperties.getMaxSize())
						.maxWaitTime(mongoSettingsProperties.getMaxWaitTime(), TimeUnit.MILLISECONDS)
						.maxConnectionIdleTime(mongoSettingsProperties.getMaxConnectionIdleTime(), TimeUnit.MILLISECONDS)
						.maxConnectionLifeTime(mongoSettingsProperties.getMaxConnectionLifeTime(), TimeUnit.MILLISECONDS)
						.maintenanceInitialDelay(mongoSettingsProperties.getMaintenanceInitialDelay(), TimeUnit.MILLISECONDS)
						.maintenanceFrequency(mongoSettingsProperties.getMaintenanceFrequency(), TimeUnit.MILLISECONDS)
						.build();
		MongoClientSettings settings = null;
		if (StringUtils.isNotBlank(this.username) && StringUtils.isNotBlank(this.authenticationDatabase) 
				&& StringUtils.isNotBlank(this.password)) {
			/**
			 * 	MongoDB权限验证配置
			 */
			MongoCredential mongoCredential = 
					MongoCredential.createScramSha1Credential(this.username, this.authenticationDatabase, this.password.toCharArray());
	       	settings = MongoClientSettings.builder().credential(mongoCredential)
	       											.applyToConnectionPoolSettings(builder->builder.applySettings(connectionPoolSettings))
	       											.applyToClusterSettings(builder-> builder.hosts(serverAddresses)).build();
		} else {
			settings = MongoClientSettings.builder().applyToConnectionPoolSettings(builder->builder.applySettings(connectionPoolSettings))
					 								.applyToClusterSettings(builder-> builder.hosts(serverAddresses)).build();
		}
	    /**
	     * 	创建MongoDB客户端
	     */
	    MongoClient mongoClient = MongoClients.create(settings);
	    
	    
	    
	    /*-----修改后实现添加时去除_class-----*/
	    MongoDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(mongoClient, database);
	    DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
	    MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, new MongoMappingContext());
	    try {
	    //  mappingConverter.setCustomConversions(beanFactory.getBean(CustomConversions.class));
	    } catch (NoSuchBeanDefinitionException ignore) {
	      System.out.println(ignore.getMessage());  
	    }
	    // 去除_calss
	    mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
	    return new MongoTemplate(factory, mappingConverter);
	    /*----------修改结束----------------------*/
	    
	    /**
	     * 	返回MongoDB模版
	     */
	 //   return new MongoTemplate(mongoClient, this.database);
	}

	/**
	 * @Description: 功能描述
	 * 		定义日志事务
	 * 
	 * @param: 参数描述
	 * @param mongoTemplate
	 * @return 
	 * @throws: 异常描述
	 *
	 * @version: v1.0.3
	 * @author: wangwk
	 * @date: 2021年7月13日 下午6:28:21 
	 *
	 * Modification History:
	 * Date         Author          Version            Description
	 * ---------------------------------------------------------*
	 * 2021年7月13日   wangwk          v1.0.3.1               创建
	 */
	@Bean(name = "syczcxMongoTransactionManager")
	public MongoTransactionManager logMongoTransactionManager(@Qualifier("mongo_test") MongoTemplate mongoTemplate) {
        return new MongoTransactionManager(mongoTemplate.getMongoDatabaseFactory());
    }
	
}
